//Teinte lorsque l'on passe sur une pièce avec une autre pièce
const PUZZLE_HOVER_TINT = '#000099';
const plural = "s";

//Variables liées à la difficulté
var PUZZLE_DIFFICULTY;
var numberHitsCurrent = 0;
var numberHitsReccord = 0;
var timeSpentCurrent = 0;
var timeSpentReccord = 0;

//Variable du chronomètre
var tempsDepart;
var tempsFin;

//Variables pour intégrer le puzzle à la page web
var _canvas;
var _stage;
var _sx = 1.0; // Width: ratio taille canvas / taille réel
var _sy = 1.0; // Height : ratio taille canvas / taille réel

//Variables pour le puzzle
var _img;
var _pieces;
var _saveInitialPieces;
var _puzzleWidth;
var _puzzleHeight;
var _pieceWidth;
var _pieceHeight;
var _currentPiece;
var _currentDropPiece;

//Variable pour faire un ratio entre la taille réelle de l'image et la taille du puzzle
var naturalWidth;
var naturalHeight;
var relativeWidth;
var relativeHeight;

//Sauvegarde de la position du curseue
var _mouse;

function initPuzzleGame(){
	//Cette fonction crée une image et met un listener sur le load de l'image
	//Initialisation des variables
	PUZZLE_DIFFICULTY = parseInt(chosenLevel) + 1;
	numberHitsCurrent = 0;
	numberHitsReccord = 0;
	timeSpentCurrent = 0;
	timeSpentReccord = 0;

	//Activation des options liées à la difficulté
	$("#numberHits").hide();
	$("#numHitsRec").hide();
	$("#timeSpentPuzzle").hide();
	
	if(chosenLevel == LEVEL_2 || chosenLevel == LEVEL_3) {
		//Affichage du div avec le nombre de coups
		$("#numberHits").show();
		
		//Mise à zero du compteur de coups courant
		$("#numHits").text("0");
		
		//Affichage du record
		numberHitsReccord = getPuzzleReccordNumHits();
		if(numberHitsReccord != null && numberHitsReccord != 0) {
			$("#numHitsRec").show();
			$("#recHits").text(numberHitsReccord);
			
			if(numberHitsReccord > 1) {
				$("#pluralReccordHitNumber").text(plural);
			}
		}
	}

	if(chosenLevel == 3) {
		//Affichage du temps reccord
		timeSpentReccord = getPuzzleReccordTime();
		if(timeSpentReccord != null && timeSpentReccord != 0) {
			$("#timeSpentPuzzle").show();
			$("#recTimeSpent").text(timeSpentReccord);
		}
	}
	
	//Chargement de l'image
	_img = new Image();
	_img.addEventListener('load',onImage,false);
	_img.src = words[chosenWord].image_src;
	
	// Affichage popup aide
	setTimeout(function() {
		$("#popupInfoJeu2").popup();
		$("#popupInfoJeu2").popup("open");
	}, 500);
}

function onImage(e){
	//Lorsque l'image est chargé, on récupère les mesures dont on a besoin
	//Taille de l'image non redimensionnée
	naturalWidth = _img.width;
	naturalHeight = _img.height;
	
	//Taille de l'image à afficher par pièce
	relativeWidth = _img.width / PUZZLE_DIFFICULTY;
	relativeHeight = _img.height / PUZZLE_DIFFICULTY;
	
	//On redimensionne l'image
	_img.width = _img.width;
	_img.height = _img.height;
	
	//Taille d'une pièce du puzzle
	_pieceWidth = Math.floor(_img.width / PUZZLE_DIFFICULTY);
	_pieceHeight = Math.floor(_img.height / PUZZLE_DIFFICULTY);
	
	//Taille du puzzle
	_puzzleWidth = _pieceWidth * PUZZLE_DIFFICULTY;
	_puzzleHeight = _pieceHeight * PUZZLE_DIFFICULTY;
	
	setCanvas();
	initPuzzle();
}

function setCanvas(){
	//Cette fonction charge l'image dans le canvas
	_canvas = document.getElementById('canvasGame2');
	_stage = _canvas.getContext('2d');
	_canvas.width = _puzzleWidth;
	_canvas.height = _puzzleHeight;
	
	_canvas.onmousedown = null;
	_canvas.onmousemove = null;
	_canvas.onmouseup = null;
	_canvas.removeEventListener('touchstart',touch_onPuzzleClick);
	_canvas.removeEventListener('touchmove',touch_updatePuzzle);
	_canvas.removeEventListener('touchend',touch_pieceDropped);
}

function initPuzzle(){
	//Cette fonction initialise les différentes variables du puzzle et on lance la création de pièces
	numberHitsCurrent = 0;
	timeSpentCurrent = 0;
	tempsDepart = new Date();
	
	_pieces = [];
	_saveInitialPieces = [];
	_mouse = {x:0,y:0};
	_currentPiece = null;
	_currentDropPiece = null;
	_stage.drawImage(_img, 0, 0, _puzzleWidth, _puzzleHeight);
	buildPieces();
}


function buildPieces(){
	//Cette fonction crée les différentes pièces du puzzle et les stocke dans un tableau
	var i;
	var piece;
	var pieceReference;
	var xPos = 0;
	var yPos = 0;
	
	for(i = 0;i < PUZZLE_DIFFICULTY * PUZZLE_DIFFICULTY;i++){
		//Initialisation des pièces 
		piece = {};
		piece.sx = xPos;
		piece.sy = yPos;
		piece.numPos = i;
		_pieces.push(piece);
		
		//_saveInitialPieces servira de référence pour checker si le puzzle est fini
		pieceReference = {};
		pieceReference.sx = xPos;
		pieceReference.sy = yPos;
		pieceReference.numPos = i;
		_saveInitialPieces.push(pieceReference);
		
		xPos += relativeWidth;
		if(xPos >= naturalWidth){
			xPos = 0;
			yPos += relativeHeight;
		}
	}
	
	//La prochaine fois que l'on clique sur la page, on lance le mélange du puzzle
	_canvas.onmousedown = shufflePuzzle;
}

function shufflePuzzle(){
	//Cette fonction affiche le puzzle mélangé
	//On mélange l'array
	_pieces = shuffleArray(_pieces);
	//On vide le canvas
	_stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);
	var i;
	var piece;
	var xPos = 0;
	var yPos = 0;
	for(i = 0;i < _pieces.length;i++){
		//Pour chaque pièce on va dessiner la partie correspondante de l'image
		piece = _pieces[i];
		piece.xPos = xPos;
		piece.yPos = yPos;
		
		_saveInitialPieces[i].xPos = xPos;
		_saveInitialPieces[i].yPos = yPos;
		
		//C'est ici que l'on faire un ratio et préciser que le x et le y de la pièce corresponde à tel x et tel y de l'image
		_stage.drawImage(_img, piece.sx, piece.sy, relativeWidth, relativeHeight, xPos, yPos, _pieceWidth, _pieceHeight);
		_stage.strokeRect(xPos, yPos, _pieceWidth, _pieceHeight);
		
		xPos += _pieceWidth;
		if(xPos >= _puzzleWidth){
			xPos = 0;
			yPos += _pieceHeight;
		}
	}
	
	// Calcul du ratio entre la taille du canvas et sa taille dans le navigateur 
	_sx = _canvas.width  / _canvas.offsetWidth;
    _sy = _canvas.height / _canvas.offsetHeight;
    console.log("ratio longueur et hauteur : " + _sx + ":" + _sy);
	
	//La prochaine fois que l'on clique sur la page, on lance la fonction de déplacement des pièces
	_canvas.onmousedown = onPuzzleClick;
	_canvas.addEventListener('touchstart', touch_onPuzzleClick, false);
}

function shuffleArray(o){
	//Fonction de mélange du tableau
	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
	return o;
}

function onPuzzleClick(e){
	var rect = _canvas.getBoundingClientRect();
	if(e.layerX || e.layerX == 0){
//		_mouse.x = e.layerX*_sx - rect.left;
//		_mouse.y = e.layerY*_sy - rect.top;
		_mouse.x = e.layerX*_sx;
		_mouse.y = e.layerY*_sy;
	}
	else if(e.offsetX || e.offsetX == 0){
		_mouse.x = e.offsetX*_sx - rect.left;
		_mouse.y = e.offsetY*_sy - rect.top;
	}
	
	checkTouchClick(e);
	
	//Récupération de la pièce cliquée
	_currentPiece = checkPieceClicked();
	
	if(_currentPiece != null){
		//On efface le rectangle avec la pièce dans le canvas
		_stage.clearRect(_currentPiece.xPos,_currentPiece.yPos,_pieceWidth,_pieceHeight);
		_stage.save();
		
		//Modification de la transparence pour que l'on puisse voir à travers la pièce déplacée
		_stage.globalAlpha = .9;
		
		//On redessine la pièce sur la souris
		_stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, relativeWidth, relativeHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
		_stage.restore();
		
		//On définie les évènements pour un mouvement de la souris et quand on lache le clique
		_canvas.onmousemove = updatePuzzle;
		_canvas.onmouseup = pieceDropped;
		_canvas.addEventListener('touchmove', touch_updatePuzzle, false );
		_canvas.addEventListener('touchend', touch_pieceDropped, false);
	}
}

function checkPieceClicked(){
	//Cette fonction récupère la pièce sur laquelle on a cliqué
	var i;
	var piece;
	
	for(i = 0;i < _pieces.length;i++){
		piece = _pieces[i];
		//récupération de la pièce par comparaison entre l'emplacement du clique de la souris et les positions des pièces
		if((_mouse.x > piece.xPos && _mouse.x <= (piece.xPos + _pieceWidth)) && (_mouse.y > piece.yPos && _mouse.y <= (piece.yPos + _pieceHeight))){
			return piece;
		}
	}
	return null;
}

function updatePuzzle(e){
	//Cette fonction met à jour le puzzle lors du déplacement d'une pièce
	_currentDropPiece = null;
	
	//On récupère la position de la souris
//	var rect = _canvas.getBoundingClientRect();
	if(e.layerX || e.layerX == 0){
//		_mouse.x = e.layerX*_sx - rect.left;
//		_mouse.y = e.layerY*_sy - rect.top;
		_mouse.x = e.layerX*_sx;
		_mouse.y = e.layerY*_sy;
	} else if(e.offsetX || e.offsetX == 0) {
//		_mouse.x = e.offsetX*_sx - rect.left;
//		_mouse.y = e.offsetY*_sy - rect.top;
		_mouse.x = e.offsetX*_sx;
		_mouse.y = e.offsetY*_sy;
	}
	
	checkTouchClick(e);
	
	//on vide le puzzle
	_stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);
	
	//On redessine les pièce en vérifiant si la souris est sur une autre pièce
	var i;
	var piece;
	for(i = 0;i < _pieces.length;i++){
		piece = _pieces[i];
		if(piece == _currentPiece){
			continue;
		}
		_stage.drawImage(_img, piece.sx, piece.sy, relativeWidth, relativeHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
		_stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight);
		if(_currentDropPiece == null){
			if((_mouse.x > piece.xPos && _mouse.x < (piece.xPos + _pieceWidth)) && (_mouse.y > piece.yPos && _mouse.y < (piece.yPos + _pieceHeight))){
				// Lorsqu'on est au dessus d'une autre pièce, on ajoute une teinte
				_currentDropPiece = piece;
				_stage.save();
				_stage.globalAlpha = .4;
				_stage.fillStyle = PUZZLE_HOVER_TINT;
				_stage.fillRect(_currentDropPiece.xPos,_currentDropPiece.yPos,_pieceWidth, _pieceHeight);
				_stage.restore();
			}
		}
	}
	
	//On dessine la pièce sur laquelle on a cliqué
	_stage.save();
	_stage.globalAlpha = .6;
	_stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, relativeWidth, relativeHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
	_stage.restore();
	_stage.strokeRect( _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth,_pieceHeight);
}

function pieceDropped(e){
	//Cette fonction gère le comportement lorsqu'on lache la pièce
	//On annule les evénements précédents
	_canvas.onmousemove = null;
	_canvas.onmouseup = null;
	
	//On inverse la position de la pièce tenue avec celle en dessous
	if(_currentDropPiece != null){
		var tmp = {xPos:_currentPiece.xPos,yPos:_currentPiece.yPos};
		_currentPiece.xPos = _currentDropPiece.xPos;
		_currentPiece.yPos = _currentDropPiece.yPos;
		_currentDropPiece.xPos = tmp.xPos;
		_currentDropPiece.yPos = tmp.yPos;
	}
	//Cette fonction redessine le puzzle maintenant que les pièces sont inversées
	resetPuzzleAndCheckWin();
}

function resetPuzzleAndCheckWin(){
	//On efface le puzzle
	_stage.clearRect(0,0,_puzzleWidth,_puzzleHeight);
	
	//On le redessine 
	var gameWin = true;
	var i;
	var piece;
	var pieceReference;
	for (i = 0; i < _pieces.length; i++) {
		piece = _pieces[i];
		_stage.drawImage(_img, piece.sx, piece.sy, relativeWidth, relativeHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
		_stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight);
		
		pieceReference = _saveInitialPieces[piece.numPos];
		if(piece.xPos != pieceReference.xPos || piece.yPos != pieceReference.yPos) {
			gameWin = false;
		}
	}
	
	//Incrémentation du nombre de coups
	numberHitsCurrent++;
	$("#numHits").text(numberHitsCurrent);
	if(numberHitsCurrent > 1){
		$("#pluralCurrentHitNumber").text(plural);
	}
	
	//On vérifie si le puzzle est fini
	if (gameWin) {
		setTimeout(gameOver, 500);
	}
}

function gameOver(){
	//Récupération du temps écoulé
	tempsFin = new Date();
	
	timeSpentCurrent = tempsFin - tempsDepart;
	timeSpentCurrent = new Date(timeSpentCurrent);
	
	playSound();
	if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/)) {
		navigator.notification.vibrate(VIBRATING_DURATION);
	}
	
	if(chosenLevel == LEVEL_3) {
		$("#displayFinalTime").show();
		$("#displayFinalTime").text("Temps : " + timeSpentCurrent.getMinutes() + ":" + timeSpentCurrent.getSeconds());
	} else {
		$("#displayFinalTime").hide();
	}
	
	puzzleComplete();
	
	_canvas.onmousedown = null;
	_canvas.onmousemove = null;
	_canvas.onmouseup = null;
	_canvas.removeEventListener('touchstart',touch_onPuzzleClick);
	_canvas.removeEventListener('touchmove',touch_updatePuzzle);
	_canvas.removeEventListener('touchend',touch_pieceDropped);
	$("#successGame2").click(); 
}

function checkTouchClick(e) {
	if(_mouse.x == 0/*-_canvas.getBoundingClientRect().left*/) {
		_mouse.x = e.targetTouches[0].pageX * _sx - _canvas.offsetLeft;
	}
	if(_mouse.y == 0/*-_canvas.getBoundingClientRect().top*/) {
		_mouse.y = e.targetTouches[0].pageY * _sy - _canvas.offsetTop;
	}
	//console.log("X:" + _mouse.x);
	//console.log("Y:" + _mouse.y);
}

function touch_onPuzzleClick(e) {
	if (!e) {
        var e = event;
    }
    e.preventDefault();
    onPuzzleClick(e);
}

function touch_updatePuzzle(e) {
	if (!e) {
        var e = event;
    }
    e.preventDefault();
    updatePuzzle(e);
}

function touch_pieceDropped(e) {
	if (!e) {
        var e = event;
    }
    e.preventDefault();
    pieceDropped(e);
}